package com.yuebook.smartrpc.framework.provider;

import com.google.common.collect.Lists;
import com.yuebook.smartrpc.framework.helper.IPHelper;
import com.yuebook.smartrpc.framework.helper.PropertyConfigHelper;
import com.yuebook.smartrpc.framework.model.ProviderService;
import com.yuebook.smartrpc.framework.zookeeper.IRegisterCenterProvider;
import com.yuebook.smartrpc.framework.zookeeper.RegisterCenter;
import java.lang.reflect.Method;
import java.util.List;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;

/**
 * @author honglei
 * @date 2018/11/18 下午7:14
 */
public class ProviderFactoryBean implements FactoryBean, InitializingBean {

    private Class<?> serviceItf;

    private Object serviceObj;

    private Method method;

    private String serverPort;

    private long timeout;

    private Object serviceProxyObj;

    private String appKey;

    private String groupName = "default";

    private int weight=1;

    private int workerThreads=10;

    @Override
    public Object getObject() throws Exception {
        return serviceProxyObj;
    }

    @Override
    public Class<?> getObjectType() {
        return serviceItf;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        //启动netty服务器
        NettyServer.singleton().start(Integer.parseInt(serverPort));
        //注册服务
        List<ProviderService> list = buildProviderServiceInfo();
        IRegisterCenterProvider registerCenterProvider = RegisterCenter.singleton();
        registerCenterProvider.registerServices(list);
    }

    private List<ProviderService> buildProviderServiceInfo() {
        List<ProviderService> providerServiceList = Lists.newArrayList();
        Method[] methods = serviceObj.getClass().getDeclaredMethods();
        String hostIp = IPHelper.localIp();
        for (Method method:methods) {
            ProviderService providerService = new ProviderService();
            providerService.setServiceItf(serviceItf);
            providerService.setServiceObject(serviceObj);
            providerService.setServiceMethod(method);
            providerService.setServiceIp(hostIp);
            providerService.setServicePort(Integer.parseInt(serverPort));
            providerService.setTimeout(timeout);
            providerService.setWeight(weight);
            providerService.setWorkerThreads(workerThreads);
            providerService.setAppKey(appKey);
            providerService.setGroupName(groupName);
            providerServiceList.add(providerService);
        }
        return providerServiceList;
    }

    public Class<?> getServiceItf() {
        return serviceItf;
    }

    public void setServiceItf(Class<?> serviceItf) {
        this.serviceItf = serviceItf;
    }

    public Object getServiceObj() {
        return serviceObj;
    }

    public void setServiceObj(Object serviceObj) {
        this.serviceObj = serviceObj;
    }

    public Method getMethod() {
        return method;
    }

    public void setMethod(Method method) {
        this.method = method;
    }

    public String getServerPort() {
        return serverPort;
    }

    public void setServerPort(String serverPort) {
        this.serverPort = serverPort;
    }

    public long getTimeout() {
        return timeout;
    }

    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }

    public Object getServiceProxyObj() {
        return serviceProxyObj;
    }

    public void setServiceProxyObj(Object serviceProxyObj) {
        this.serviceProxyObj = serviceProxyObj;
    }

    public String getAppKey() {
        return appKey;
    }

    public void setAppKey(String appKey) {
        this.appKey = appKey;
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public int getWorkerThreads() {
        return workerThreads;
    }

    public void setWorkerThreads(int workerThreads) {
        this.workerThreads = workerThreads;
    }
}
